(function() {
  const DELAY_OF_CHECKING_EDIT = 1500;
  var checkEditTimer;
  
  var $shortcutSetting = $('#switches-setting-wrapper');
  var $startupBtn = $('#startup-btn');
  var $saveBtn = $('#save-btn');
  var $cancelBtn = $('#setting-cancel-btn');
  
  var ss = window.ShortcutSetting = {
    isNewShortcut: false,
    modifiedShortcutId: '',
    modifiedShortcutData: {},
    setup: function() {
      $startupBtn.on('click', function() {
        var shortcutId = ss.modifiedShortcutId;
        var needToSave = ss.isNewShortcut || ss.isEdited();
        var saveResult;
        if (needToSave) {
          saveResult = ss.save();
          if (saveResult == shortcutId)
            Manager.startup(shortcutId);
        } else {
          Manager.startup(shortcutId);
        }
        clearInterval(checkEditTimer);
      });

      $cancelBtn.on('click', function() {
        if (Manager.createdShortcut()) {
          ShortcutList.show();
        } else {
          Welcome.show();
        }
        ss.hide();
        clearInterval(checkEditTimer);
      });

      $saveBtn.on('click', ss.save);

      ShortcutBaseInfo.setup();
      ShortcutIcon.setup();
      ShortcutTheme.setup();
      AdvancedSetting.setup();
    },

    init: function() {
      ShortcutBaseInfo.init();
      ShortcutIcon.init();
      ShortcutTheme.init();
      AdvancedSetting.init();

      ss.isNewShortcut = false;
      ss.modifiedShortcutId = '';
      ss.modifiedShortcutData = {};

      ss.setSaveButtonState(true);

      // Enable save and startup button if user edited the shortcut.
      checkEditTimer = setInterval(function() {
        if (ss.isEdited()) {
          ss.setSaveButtonState(false);
          ss.setStartupButtonState(false);
          clearInterval(checkEditTimer);
        }
      }, DELAY_OF_CHECKING_EDIT);
    },
    
    show: function() {
      $shortcutSetting.show();
      $startupBtn.show();
      $saveBtn.show();
      $cancelBtn.show();
    },

    hide: function() {
      $shortcutSetting.hide();
      $startupBtn.hide();
      $saveBtn.hide();
      $cancelBtn.hide();
    },

    generateShortcutId: function() {
      return 'shortcut-' + new Date().getTime();
    },

    createShortcut: function() {
      ss.show();
      ss.init();
      ss.isNewShortcut = true;
      var id = ss.modifiedShortcutId = ss.generateShortcutId();
      var userDataFolder = AdvancedSetting.generateUserDataFolder(id);
      
      // Add --no-first-run switch to ensure succeed to apply theme.
      AdvancedSetting.addSwitch('--no-first-run', '');
      AdvancedSetting.setUserDataFolder(userDataFolder);
      ss.modifiedShortcutData = ss.generateShortcutData();

      // Disable startup button.
      ss.setStartupButtonState(true);
    },

    setSaveButtonState: function(disabled) {
      $saveBtn.get().disabled = disabled;
    },

    setStartupButtonState: function(disabled) {
      $startupBtn.get().disabled = disabled;
    },
    
    /**
     * Apply shortcut data into shortcut setting page.
     * @param {Object} shortcut
     *   required keys: id, name, path, iconId, icon, iconFile, iconIndex,
     *   themeName, userDataFolder, switches
     */
    applyShortcutData: function(shortcut) {
      ss.init();
      ShortcutBaseInfo.applyShortcutData(shortcut.name, shortcut.path);
      ShortcutIcon.applyIcon(shortcut);
      ShortcutTheme.applyTheme(shortcut.themeName);
      AdvancedSetting.applyShortcutData(shortcut);

      ss.modifiedShortcutData = ss.generateShortcutData();
      ss.modifiedShortcutId = shortcut.id;
    },

    generateShortcutData: function() {
      var baseData = ShortcutBaseInfo.generateShortcutData();
      var iconData = ShortcutIcon.getIconData();
      var themeData = ShortcutTheme.getThemeData();
      var switchData = AdvancedSetting.generateShortcutData();
      var shortcut = {};
      shortcut.name = baseData.name;
      shortcut.path = baseData.path;
      shortcut.icon = iconData;
      shortcut.theme = themeData;
      shortcut.userDataFolder = switchData.userDataFolder;
      shortcut.switches = switchData.switches;

      return shortcut;
    },

    isEdited: function() {
      var generatedShortcutInfo = ss.generateShortcutData();
      return !$.compareObject(generatedShortcutInfo, ss.modifiedShortcutData);
    },

    validate: function() {
      // Shortcut name can't be empty
      if (!ShortcutBaseInfo.validateName()) {
        return false;
      }

      // Shortcut path can't be empty
      if (!ShortcutBaseInfo.validatePath()) {
        return false;
      }

      return AdvancedSetting.validateUserDataFolder();
    },

    constructShortcutData: function(id, shortcut) {
      var iconId = shortcut.icon.id;
      var userDataFolder = shortcut.userDataFolder;

      // Construct switches parameter string
      var switches = shortcut.switches;
      var params = [];
      for (var _switch in switches) {
        if (switches[_switch])
          params.push(_switch + '=' + switches[_switch]);
        else
          params.push(_switch);
      }

      params.push('--icon-id=' + iconId);
      params.push('--user-data-dir="' + userDataFolder + '"');
      params = params.join(' ');

      return {
        id: id,
        fileName: shortcut.name,
        filePath: shortcut.path,
        iconFile: shortcut.icon.file,
        iconIndex: shortcut.icon.index,
        params: params,
        themeName: shortcut.theme.id,
        themeUrl: shortcut.theme.url
      };
    },

    constructShortcutStorage: function(shortcut) {
      return {
        name: shortcut.name,
        path: shortcut.path,
        iconId: shortcut.icon.id,
        themeName: shortcut.theme.name
      };
    },

    constructShortcutItem: function(shortcutId, shortcut) {
      var icon = shortcut.icon;
      var iconId = icon.id;
      if (iconId == 'default')
        icon.src = Fs.getDefaultIconData();
      return {
        id: shortcutId,
        name: shortcut.name,
        path: shortcut.path,
        iconId: iconId,
        icon: icon.src,
        iconFile: icon.file,
        iconIndex: icon.index,
        themeName: shortcut.theme.name,
        userDataFolder: shortcut.userDataFolder,
        switches: shortcut.switches
      };
    },
    
    save: function() {
      if (!ss.validate()) {
        return false;
      }

      if (!ss.isEdited()) {
        Tip.alert('no_modification');
        return false;
      }

      var shortcut = ss.generateShortcutData();
      var shortcutId = ss.modifiedShortcutId;

      var shortcutData = ss.constructShortcutData(shortcutId, shortcut);
      var shortcutStorage = ss.constructShortcutStorage(shortcut);
      var shortcutItem = ss.constructShortcutItem(shortcutId, shortcut);
      var result;

      if (ss.isNewShortcut) {
        // Create a new shortcut.
        var saveResult = Fs.saveShortcut(shortcutData);
        result = $.type(saveResult);
        if (result == 'string') {
          ShortcutsStorage.addShortcut(shortcutId, shortcutStorage);
          ShortcutList.addShortcut(shortcutItem);
          succeed('save_shortcut_done');
        } else if (result == 'number') {
          return Tip.alert('save_failed_' + saveResult);
        }
      } else {
        // Update an existent shortcut.
        var updateResult = Fs.updateShortcut(ss.modifiedShortcutData.name,
          ss.modifiedShortcutData.path, shortcutData);
        result = $.type(updateResult);
        if (result == 'string') {
          ShortcutsStorage.updateShortcut(shortcutId, shortcutStorage);
          ShortcutList.updateShortcut(shortcutItem, $id(shortcutId));
          succeed('update_shortcut_done');
        } else if (result == 'number') {
          return Tip.alert('save_failed_' + updateResult);
        }
      }

      // Succeed callback.
      function succeed(type) {
        ss.modifiedShortcutData = ss.generateShortcutData();
        ss.isNewShortcut = false;
        Tip.alert(type);
        ss.hide();
        ShortcutList.show();
        clearInterval(checkEditTimer);
      }

      return shortcutId;
    }
  }
})();